package main

import (
	"fmt"
	"math/rand"
	"sync"
)

type ChannelPool struct {
	cpFuncs []CPFunc
	data    chan interface{}
	wg      sync.WaitGroup
}

type CPFunc func() interface{}

func CP() *ChannelPool {

	return &ChannelPool{
		cpFuncs: make([]CPFunc, 10),
		data:    make(chan interface{}),
		wg:      sync.WaitGroup{},
	}
}

func (this *ChannelPool) Add(f CPFunc) {
	this.cpFuncs = append(this.cpFuncs, f)

}

func (this *ChannelPool) do() {

	for _, f := range this.cpFuncs {
		this.wg.Add(1)
		go func() {
			defer this.wg.Done()
			this.data <- f()
		}()
	}
}
func (this *ChannelPool) Range(f func(value interface{})) {
	this.do()
	go func() {
		defer close(this.data)
		this.wg.Wait()
	}()

	for item := range this.data {
		f(item)
	}

}

func main() {

	cp := CP()

	for i := 0; i < 1000; i++ {
		cp.Add(func() interface{} {
			return rand.Intn(10)
		})
	}

	cp.Range(func(value interface{}) {
		fmt.Println(value)
	})

}
